package com.spring.rpc.config;

import com.spring.rpc.remoting.client.RabbitProxyFactoryBean;
import com.spring.rpc.service.IHelloWord;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.remoting.client.AmqpProxyFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.support.ExecutorServiceAdapter;

import java.util.UUID;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
 * @Description
 * @Author cuiyaosheng
 * @Date 2018-03-19 18:32
 * @Modified by:
 **/
@Configuration
public class RabbitMQClientConfiguration {
    /**
     * 连接信息
     */
//    private String hostName = "10.7.1.20";
//    private int port = 5670;
//    private String userName = "admin";
//    private String passWord = "admin";
//    private String hostName = "10.21.25.153";
//    private int port = 5672;
//    private String userName = "guest";
//    private String passWord = "guest";

//    private String hostName = "10.0.21.184";
//    private int port = 5672;
//    private String userName = "admin";
//    private String passWord = "admin@microservice!";

//    private String hostName = "10.0.20.153";
//    private int port = 5672;
//    private String userName = "admin";
//    private String passWord = "admin@microservice!";

    private String hostName = "47.92.95.53";
    private int port = 5674;
    private String userName = "guest";
    private String passWord = "guest";

    /**
     * 请求信息
     */
    private String EXCHANGE_NAME = "app.remoting.exchange";
    private String ROUTEKEY_NAME = "app.remoting.binding";

    /**
     * 回执信息
     */
    private String REPLY_QUEUE_NAME = "app.remoting.queue.reply";
    private String REPLY_ROUTEKEY_NAME = "app.remoting.binding.reply";
    private String REPLY_ADDRESS_NAME = EXCHANGE_NAME + "/" + REPLY_ROUTEKEY_NAME;

    @Bean
    public ConnectionFactory connectionFactory() {
        //TODO make it possible to customize in subclasses.
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory(hostName);
        connectionFactory.setUsername(userName);
        connectionFactory.setPassword(passWord);
        connectionFactory.setPort(port);
        return connectionFactory;
    }

    @Bean
    public AmqpAdmin rabbitAdmin() {
        return new RabbitAdmin(connectionFactory());
    }

    /**
     * 模板
     * @return
     */
    @Bean
    public RabbitTemplate rabbitTemplate() {
        RabbitTemplate template = new RabbitTemplate(connectionFactory());
        template.setExchange(EXCHANGE_NAME);
        template.setRoutingKey(ROUTEKEY_NAME);
        template.setReplyAddress(REPLY_ADDRESS_NAME);
        template.setReplyTimeout(20000);
//        template.setCorrelationKey(UUID.randomUUID().toString());
        return template;
    }

    /**
     * 回执队列
     * @return
     */
    @Bean
    public Queue replyQueue() {
        return new Queue(REPLY_QUEUE_NAME,true);
    }
    /**
     * 回执交换机
     * @return
     */
    @Bean
    public DirectExchange replyExchange() {
        return new DirectExchange(EXCHANGE_NAME);
    }

    /**
     * 回执绑定
     * @return
     */
    @Bean
    public Binding replyDataBinding() {
        return BindingBuilder.bind(replyQueue()).to(replyExchange()).with(REPLY_ROUTEKEY_NAME);
    }

    @Bean
    Executor executor(){
        return Executors.newCachedThreadPool();
    }
    /**
     * 回执监听容器(消费者)
     * @return
     */
    @Bean
    public SimpleMessageListenerContainer replyListenerContainer() {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory());
        container.setTaskExecutor(executor());
        container.setQueues(replyQueue());
        container.setConcurrentConsumers(5);
        container.setMaxConcurrentConsumers(50);
        container.setPrefetchCount(1);
        container.setMessageListener(rabbitTemplate());
        return container;
    }


    /**
     * 客户端服务调用
     * @return
     */
    @Bean
    RabbitProxyFactoryBean amqpProxyFactoryBean(){
        RabbitProxyFactoryBean rabbitProxyFactoryBean = new RabbitProxyFactoryBean();
        rabbitProxyFactoryBean.setRabbitTemplate(rabbitTemplate());
        rabbitProxyFactoryBean.setRoutingKey(ROUTEKEY_NAME);
        rabbitProxyFactoryBean.setServiceInterface(IHelloWord.class);
        return rabbitProxyFactoryBean;
    }
}
